package com.bnq.logc.data

import cn.ucloud.ufile.api.ApiError
import cn.ucloud.ufile.bean.UfileErrorBean
import com.tencent.cos.xml.exception.CosXmlClientException
import com.tencent.cos.xml.exception.CosXmlServiceException
import kotlinx.coroutines.Dispatchers
import java.io.File

data class UploadResult(val file:File,val cloudPathName:String,val status: UploadStatus,val error:FileUploadError? = null)

interface FileUploadError{
    fun getSimpleErrorInfoString():String

    fun getErrorMessageString():String
}

data class UfileUploadError(val error:Exception?,val apiError: ApiError?, val responseErrorBean: UfileErrorBean?):FileUploadError{
    override fun getSimpleErrorInfoString():String{
        return "error: ${error?.toString()} , apiError: ${apiError?.toString()} , responseError: ${responseErrorBean?.toString()}"
    }

    override fun getErrorMessageString(): String {
        return error?.message?:apiError?.message?:responseErrorBean?.errMsg?:""
    }
}

data class CosFileUploadError(val clientError: CosXmlClientException?,val serverError: CosXmlServiceException?):FileUploadError{
    override fun getSimpleErrorInfoString(): String {
        return "clientError: ${clientError?.toString()} , serverError: ${serverError?.toString()}"
    }

    override fun getErrorMessageString(): String {
        return clientError?.message?:serverError?.message?:""
    }
}

data class CheckUploadResult(val result:List<UploadResult>?,val e:Throwable?,val isUploadLog:Boolean) {
    fun getUploadSuccessRateString(): String {
        if(result == null || result.isEmpty()){
            return "0/0"
        }
        val success = result.count { it.status == UploadStatus.Success}
        val count = result.size
        return "$success/$count"
    }
    fun getUploadErrorInfoString():String {
        if(result == null || result.isEmpty()){
            return ""
        }
        val sb = StringBuilder()
        result.forEach {
            sb
                .append(it.file.absolutePath).append(" , ")
                .append(it.cloudPathName).append(" , ")
                .append(it.status).append(" , ")
                .append(it.error?.getSimpleErrorInfoString()).append("\n")
        }
        return sb.toString()
    }
    fun getSimpleUploadErrorInfoString():String {
        if(result == null || result.isEmpty()){
            return ""
        }
        val sb = StringBuilder()
        result.forEach {
            if(it.status == UploadStatus.Fail){
                sb
                    .append(it.file.absolutePath).append(" , ")
                    .append(it.cloudPathName).append(" , ")
                    .append(it.status).append(" , ")
                    .append(it.error?.getSimpleErrorInfoString()).append(" # ")
            }
        }
        return sb.toString()
    }

    fun getDetailUploadResultInfoString():String {
        val logStr = "uploadResult:${getUploadSuccessRateString()}, e: ${e}, isUploadLog: ${isUploadLog}, uploadError: ${getUploadErrorInfoString()}"
        return logStr
    }

    fun isAllSuccess():Boolean{
        val errList = result?.find { it.status == UploadStatus.Fail }
        return errList == null
    }

    fun getCloudPathNames():List<String>{
        return result?.map { it.cloudPathName }?: emptyList()
    }

    fun getFormatUploadResultString(simple:Boolean = true):String{
        val sb = StringBuilder()
        sb.append("成功比例: ${getUploadSuccessRateString()}\n")
        if(e != null){
            sb.append("错误信息: ${e.message}\n")
        }
        if(result != null && result.isNotEmpty()){
            sb.append("文件上传结果: \n")
            result.forEach {
                if(it.status == UploadStatus.Success){
                    sb  .append(it.status).append(": ")
                        .append(if(simple)it.file.name else it.file.absolutePath).append(" 已上传到远程 ")
                        .append(it.cloudPathName).append("\n")

                }else{
                    sb  .append(it.status).append(": ")
                        .append(if(simple)it.file.name else it.file.absolutePath).append(" 上传失败 ")
                        .append(it.error?.getErrorMessageString()).append("\n")
                }
            }
        }
        return sb.toString()
    }
}

enum class UploadStatus{
    Success,
    Fail,
}
